﻿using Shop.Core.Repository;
using Shop.Core.Share;
using Shop.IServices.Admin;
using Shop.Model.Dto.Admin.JurUserRole;
using Shop.Model.Entity.Jur;
using Shop.Model.View.Admin.JurUserRole;
using SqlSugar;

namespace Shop.Services.Admin;

public class JurRoleService: IJurRoleService
{
    private readonly RepositoryBase<JurRole> _roleRepository;

    public JurRoleService(RepositoryBase<JurRole> roleRepository)
    {
        _roleRepository = roleRepository;
    }

    /// <summary>
    /// 添加角色
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<AppResult> Add(UserRoleAddDto dto)
    {
        var exit = await _roleRepository.AnyAsync(x => x.Name.Equals(dto.Name));
        if (exit)
            throw new Exception("角色名已存在");
        await _roleRepository.InsertAsync(new JurRole { Name = dto.Name, State = 0, Comments = dto.Comments, CreateTime = DateTime.Now });
        return new AppResult();
    }

    /// <summary>
    /// 修改角色
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<AppResult> Modify(UserRoleModifyDto dto)
    {
        var role = await _roleRepository.GetByIdAsync(dto.Id);
        if (role == null)
            throw new Exception("参数错误，找不到该角色");
        role.Name = dto.Name;
        role.Comments = dto.Comments;
        role.UpdateTime = DateTime.Now;
        await _roleRepository.UpdateAsync(role);
        return new AppResult();
    }

    /// <summary>
    /// 删除角色
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<AppResult> Delete(DeleteDto dto)
    {
        var role = await _roleRepository.GetByIdAsync(dto.Id);
        if (role == null)
            throw new Exception("找不到角色");
        role.State = -1;
        role.UpdateTime = DateTime.Now;
        await _roleRepository.UpdateAsync(role);
        return new AppResult();
    }

    /// <summary>
    /// 获取角色列表
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult<PageModel<SystemUserRoleVo>> PageSearchRole(SysRolePageSearchDto dto)
    {
        var records = 0;
        var data = _roleRepository.Queryable<JurRole>()
            .WhereIF(!string.IsNullOrWhiteSpace(dto.RoleName), x => x.Name.Contains(dto.RoleName))
            .OrderByDescending(x => x.CreateTime)
            .Select(x => new SystemUserRoleVo
            {
                Id = x.Id,
                Name = x.Name,
                Comments = x.Comments,
                CreateTime = x.CreateTime
            })
            .ToPageList(dto.PageIndex, dto.PageSize, ref records);
        return new PageModel<SystemUserRoleVo>(dto, data, records);
    }

    /// <summary>
    /// 获取所有对象
    /// </summary>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<AppResult<List<SystemUserRoleVo>>> GetAllRoleList()
    =>await _roleRepository.Where(x => x.State == 0).Select<SystemUserRoleVo>().ToListAsync();

    /// <summary>
    /// 添加权限
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<AppResult> AddAccess(UserRoleAddMenuDto dto)
    {
        var role = await _roleRepository.GetFirstAsync(x => x.Id == dto.Id);
        if (role == null)
            throw new Exception("参数错误");
        _roleRepository.BeginTran();
        var db = _roleRepository.Change<JurRoleMenu>();
        await db.DeleteAsync(x => x.RoleId == role.Id);
        if (dto.Data.Any())
        {
            var data = dto.Data.Select(x => new JurRoleMenu {
                RoleId = role.Id,
                MenuId = x,
                CreateTime = DateTime.Now,
            }).ToList();
            await db.InsertRangeAsync(data);
        }
        _roleRepository.CommitTran();
        return new AppResult();
    }

    /// <summary>
    /// 角色权限树
    /// </summary>
    /// <param name="roleId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<AppResult<SysMenuTreeVo[]>> GetRoleMenuTree(long roleId)
    {
        var data =  await _roleRepository.Queryable<JurMenu,JurRoleMenu>((m, rm) => new object[]
                {
                    JoinType.Left, rm.MenuId == m.Id && rm.RoleId == roleId
                })
            .Where((m, rm) => m.State == 0)
            .Select((m, rm) => new SysMenuTreeVo
            {
                Id = m.Id,
                Authority = m.Authority,
                Checked = rm.Id != null,
                Component = m.Component,
                CreateTime = m.CreateTime,
                MenuName = m.MenuName,
                MenuType = m.MenuType,
                ParentId = m.ParentId,
                Path = m.Path
            })
            .ToListAsync();

        var result = data.FindAll(x => x.ParentId == 0).ToArray();
        foreach(var item in result)
        {
            if (item.MenuType == 0)
            {
                var children = data.FindAll(x => x.ParentId == item.Id).ToArray();
                foreach (var child in children)
                {
                    if (child.MenuType == 0)
                        child.Children = data.FindAll(x => x.ParentId == child.Id).ToArray();
                }

                item.Children = children;
            }
        }
        return result;
    }
}